<?php
namespace application\classes\Core;

use \ReflectionClass;

/**
 * IOC容器
 * @author caoyong
 * @modify
 *      #2015-03-14 by version 1.2.1
 * 		1.修复获取实例的bug
 * 
 * 		#2015-01-21 by version 1.2.0
 * 		1.加入自动注入功能
 * 		2.类方法不再使用静态方法
 * 		3.不兼容旧容器
 */
class Container
{
	/**
	 * 已注册的实例
	 * @var array
	 */
	protected $instances = array();

	/**
	 * 实例的依赖定义
	 * @var array
	 */
	protected $definitions;
	
	/**
	 * 实例的反射对象
	 * @var array
	 */
	protected $reflections;
	
	public function get($class,array $params = array())
	{
		if (isset($this->instances[$class]) && $object = $this->instances[$class])
		{
			return $object;
		}
		
		list($reflection,$dependencies) = $this->getDependencies($class);

		$object = $reflection->newInstanceArgs($dependencies);
		foreach ($params as $name => $value)
		{
			$object->$name = $value;
		}
		$this->instances[$class] = $object;
		return $object;
	}
	
	public function set($class,array $dependencies = array())
	{
		$this->definitions[$class] = $dependencies;
		if ($this->has($class))
		{
			unset($this->instances[$class]);
		}
		return $this;
	}
	
	public function has($class)
	{
		return isset($this->instances[$class]);
	}
	
	protected function getDependencies($class)
	{
		if (isset($this->reflections[$class]) && isset($this->definitions[$class]))
		{
			return array($this->reflections($class),$this->definitions[$class]);
		}
		
		$ref = new ReflectionClass($class);
		$dependencies = array();
		$constructor = $ref->getConstructor();
		
		if (!is_null($constructor))
		{			
			foreach ($constructor->getParameters() as $param)
			{
				if ($param->isDefaultValueAvailable())
				{
					$dependencies[] = $param->getDefaultValue();
				}
				else
				{
					$class = $param->getClass()->name;
					$dependencies[] = $this->get($class);
				}
			}
		}
		$this->reflections[$class] = $ref;
		$this->definitions[$class] = $dependencies;
		return array($ref,$dependencies);
	}
}